﻿//NGit is derived from jgit (http://eclipse.org/jgit).
//Copyright owners are documented in jgit's IP log.

//This program and the accompanying materials are made available
//under the terms of the Eclipse Distribution License v1.0 which
//accompanies this distribution, is reproduced below, and is
//available at http://www.eclipse.org/org/documents/edl-v10.php

//All rights reserved.

//Redistribution and use in source and binary forms, with or
//without modification, are permitted provided that the following
//conditions are met:

//- Redistributions of source code must retain the above copyright
//  notice, this list of conditions and the following disclaimer.

//- Redistributions in binary form must reproduce the above
//  copyright notice, this list of conditions and the following
//  disclaimer in the documentation and/or other materials provided
//  with the distribution.

//- Neither the name of the Eclipse Foundation, Inc. nor the
//  names of its contributors may be used to endorse or promote
//  products derived from this software without specific prior
//  written permission.

//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
//CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
//INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
//SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
//NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
//STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;



namespace SharpDBM.helper
{
    public class ReferenceQueue<T>
    {
        private Queue<Reference<T>> queue;

        public ReferenceQueue()
        {
            this.queue = new Queue<Reference<T>>();
        }

        internal bool Add(Reference<T> t)
        {
            Queue<Reference<T>> queue = this.queue;
            lock (queue)
            {
                if (this.queue.Contains(t))
                {
                    return false;
                }
                this.queue.Enqueue(t);
                return true;
            }
        }

        public Reference<T> Poll()
        {
            Queue<Reference<T>> queue = this.queue;
            lock (queue)
            {
                if (this.queue.Count > 0)
                {
                    return this.queue.Dequeue();
                }
                return null;
            }
        }
    }


    internal class SoftReference<T> : Reference<T>
    {
        private ReferenceQueue<T> queue;
        private T value;

        public SoftReference()
        {

        }
        
        public SoftReference(T val)
        {
            this.value = val;
        }

        public SoftReference(T val, ReferenceQueue<T> queue)
        {
            this.value = val;
            this.queue = queue;
        }

        public void Clear()
        {
            this.value = default(T);
        }

        public bool Enqueue()
        {
            if (this.queue == null)
            {
                return false;
            }
            return this.queue.Add(this);
        }

        public override T Get()
        {
            return this.value;
        }
    }


    public abstract class Reference<T>
    {
        protected Reference()
        {
        }

        public abstract T Get();
    }
}
